package com.xz.audit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.audit.domain.AuditInfo;
import com.xz.audit.domain.AuditNode;
import com.xz.audit.domain.AuditProcess;
import com.xz.audit.dto.AuditDto;
import com.xz.audit.dto.AuditInfoDto;
import com.xz.audit.mapper.AuditInfoMapper;
import com.xz.audit.service.IAuditInfoService;
import com.xz.audit.service.IAuditNodeService;
import com.xz.audit.service.IAuditProcessService;
import com.xz.common.core.domain.entity.SysRole;
import com.xz.common.core.domain.entity.SysUser;
import com.xz.common.core.domain.model.LoginUser;
import com.xz.common.exception.ServiceException;
import com.xz.common.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 审核流程Service业务层处理
 *
 * @author xz
 * @date 2023-09-27
 */
@Service
public class AuditInfoServiceImpl extends ServiceImpl<AuditInfoMapper, AuditInfo> implements IAuditInfoService {
    @Autowired
    private AuditInfoMapper auditInfoMapper;
    @Autowired
    private IAuditNodeService auditNodeService;
    @Autowired
    private IAuditProcessService iAuditProcessService;



    //成功
    public static final Integer  SUCCESS= 1;
    //最后节点
    public static final Integer  FINAL_NODE= 3;
    //第一节点，重新发起
    public static final Integer  FIRST_NODE= 4;

    /**
     * 查询审核流程
     *
     * @param id 审核流程主键
     * @return 审核流程
     */
    @Override
    public AuditInfo selectAuditInfoById(Long id) {
        return auditInfoMapper.selectAuditInfoById(id);
    }

    /**
     * 查询审核流程列表
     *
     * @param auditInfo 审核流程
     * @return 审核流程
     */
    @Override
    public List<AuditInfo> selectAuditInfoList(AuditInfo auditInfo) {
        return auditInfoMapper.selectAuditInfoList(auditInfo);
    }



    /**
     * 新增审核流程
     *
     * @param auditInfoDto 审核流程
     * @return 结果
     */
    @Override
    public int insertAuditInfo(AuditInfoDto auditInfoDto) {
        //查询当前订单是否已经开始审核
        List<AuditInfo> auditInfoList = baseMapper.selectList(new QueryWrapper<AuditInfo>().eq("biz_no", auditInfoDto.getBizNo()).eq("biz_type",auditInfoDto.getBizType()));
        if(!CollectionUtils.isEmpty(auditInfoList)){
            throw new ServiceException("审批已发起,请务重复发起");
        }
        //校验是否已经配置审核流程
        List<AuditProcess> auditProcessList = iAuditProcessService.list(new QueryWrapper<AuditProcess>().eq("biz_type", auditInfoDto.getBizType()).eq("status", 0));
        if(CollectionUtils.isEmpty(auditProcessList)){
           throw new ServiceException("流程不存在");
        }
        //校验流程是否有有配置节点
        AuditProcess auditProcess = auditProcessList.get(0);
        //新增发起记录
        AuditInfo initiateAuditInfo = initiateDataFilling(SecurityUtils.getLoginUser().getUser(), auditInfoDto);
        auditInfoMapper.insertAuditInfo(initiateAuditInfo);
        //查询流程节点
        List<AuditNode> nodeList = auditNodeService.list(new QueryWrapper<AuditNode>().eq("process_id",auditProcess.getId()).orderByAsc("audit_sort"));
        //插入第一审核节点
        AuditNode auditNode = nodeList.get(0);
        AuditInfo auditInfo = dataFilling(auditNode, auditInfoDto);
        auditInfoMapper.insertAuditInfo(auditInfo);
        return SUCCESS;
    }

    /**
     * 数据填充
     * @param auditNode
     * @param auditInfoDto
     * @return
     */
    public AuditInfo dataFilling(AuditNode auditNode,AuditInfoDto auditInfoDto){
        AuditInfo info=new AuditInfo();
        info.setBizType(auditInfoDto.getBizType());
        info.setBizNo(auditInfoDto.getBizNo());
        info.setNodeId(auditNode.getId());
        info.setAuditStatus(1);
        info.setTenantId(auditNode.getTenantId());
        info.setCreateTime(new Date());
        info.setCreateBy(SecurityUtils.getUserId());
        info.setAuditTypeMethod(auditNode.getAuditMethod());
        info.setAuditTypeId(auditNode.getAuditId());
        info.setAuditTypeName(auditNode.getAuditName());
        info.setNodeName(auditNode.getNodeName());
        if(auditNode.getAuditMethod()==2){
            info.setAuditId(auditNode.getAuditId());
            info.setAuditName(auditNode.getAuditName());
        }
        return info;
    }
    /**
     * 数据填充--发起数据填充
     * @param auditInfoDto
     * @return
     */
    public AuditInfo initiateDataFilling(SysUser sysUser, AuditInfoDto auditInfoDto){
        AuditInfo info=new AuditInfo();
        info.setBizNo(auditInfoDto.getBizNo());
        info.setNodeId(0L);
        info.setAuditStatus(2);
        info.setAuditId(sysUser.getUserId());
        info.setAuditName(sysUser.getUserName());
        info.setAuditTime(new Date());
        info.setTenantId(sysUser.getTenantId());
        info.setCreateTime(new Date());
        info.setCreateBy(SecurityUtils.getUserId());
        info.setBizType(auditInfoDto.getBizType());
        return info;
    }

    /**
     * 修改审核流程
     *
     * @param auditDto 审核流程
     * @return 结果
     */
    @Override
    public int updateAuditInfo(AuditDto auditDto) {
        //获取当前审核节点
        List<AuditInfo> auditInfoList = baseMapper.selectList(new QueryWrapper<AuditInfo>().eq("biz_no", auditDto.getBizNo()).eq("audit_status",1).eq("biz_type",auditDto.getBizType()));
        if(CollectionUtils.isEmpty(auditInfoList)){
           throw new ServiceException("审核失败");
        }
        AuditInfo info = auditInfoList.get(0);
        info.setUpdateTime(new Date());
        info.setAuditTime(new Date());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        info.setUpdateBy(loginUser.getUserId());
        info.setAuditId(loginUser.getUserId());
        info.setAuditStatus(auditDto.getAuditStatus()==1?2:3);
        info.setAuditName(loginUser.getUsername());
        info.setAuditNote(auditDto.getRemark());
        int updated = baseMapper.updateById(info);
        if(updated==0){
            throw new ServiceException("审核失败");
        }
        //校验当前节点
        AuditNode serviceById = auditNodeService.getById(info.getNodeId());
        if(Objects.isNull(serviceById)){
            throw new ServiceException("流程不存在");
        }
        List<AuditNode> auditNodeList=null;
        if(auditDto.getAuditStatus()==2){//拒绝
            //是否是第一节点
            auditNodeList = auditNodeService.list(new QueryWrapper<AuditNode>().lt("audit_sort", serviceById.getAuditSort()).orderByDesc("audit_sort"));
            if(CollectionUtils.isEmpty(auditNodeList)){
                return FIRST_NODE;
            }
        }else{
            //校验是否有下一节点
            auditNodeList = auditNodeService.list(new QueryWrapper<AuditNode>().gt("audit_sort", serviceById.getAuditSort()).orderByAsc("audit_sort"));
            if(CollectionUtils.isEmpty(auditNodeList)){
                return FINAL_NODE;
            }
        }
        //生成待审核信息
        AuditInfoDto auditInfoDto = new AuditInfoDto(1, auditDto.getBizNo(),1);
        AuditNode auditNode = auditNodeList.get(0);
        AuditInfo dataed = dataFilling(auditNode, auditInfoDto);
        auditInfoMapper.insertAuditInfo(dataed);
        return SUCCESS;
    }

    /**
     * 批量删除审核流程
     *
     * @param ids 需要删除的审核流程主键
     * @return 结果
     */
    @Override
    public int deleteAuditInfoByIds(Long[] ids) {
        return auditInfoMapper.deleteAuditInfoByIds(ids);
    }

    /**
     * 删除审核流程信息
     *
     * @param id 审核流程主键
     * @return 结果
     */
    @Override
    public int deleteAuditInfoById(Long id) {
        return auditInfoMapper.deleteAuditInfoById(id);
    }

    /**
     * 审核权限
     * @param id
     * @return
     */
    @Override
    public AuditInfo iAuditInfoService(Long id, SysUser sysUser,List<AuditInfo> auditInfoList) {
        AuditInfo auditInfo=new AuditInfo();
        List<SysRole> roles = sysUser.getRoles();
        Long roleId;
        if(!CollectionUtils.isEmpty(roles)){
            roleId= roles.get(0).getRoleId();
        } else {
            roleId = null;
        }
        List<AuditInfo> list = auditInfoList.stream().filter(i -> i.getBizNo().equals(id.toString())).collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(list)){
            AuditInfo info = list.get(0);
            auditInfo.setNodeName(info.getNodeName());
            if(info.getAuditTypeMethod()==1){//1.角色 2.审核人 3.部门
                if(roleId!=null&& Objects.equals(info.getAuditTypeId(), roleId)){
                    auditInfo.setAuditBut(1);
                }
            }
            if(info.getAuditTypeMethod()==2){
                if(sysUser.getUserId().equals(info.getAuditTypeId())){
                    auditInfo.setAuditBut(1);
                }
            }
            if(info.getAuditTypeMethod()==3){
                if(sysUser.getDeptId().equals(info.getAuditTypeId())){
                    auditInfo.setAuditBut(1);
                }
            }
        }
        return auditInfo;
    }
}
